//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.vpncrypto;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Provider.Service;
import java.util.Enumeration;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import sun.security.jca.GetInstance;
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;

final class JceSecurity {
    static final SecureRandom RANDOM = new SecureRandom();
    private static javax.vpncrypto.CryptoPermissions defaultPolicy = null;
    private static javax.vpncrypto.CryptoPermissions exemptPolicy = null;
    private static final Map<Provider, Object> verificationResults = new IdentityHashMap();
    private static final Map<Provider, Object> verifyingProviders = new IdentityHashMap();
    private static final boolean isRestricted;
    private static final Debug debug = Debug.getInstance("jca", "Cipher");
    private static final Object PROVIDER_VERIFIED;
    private static final URL NULL_URL;
    private static final Map<Class<?>, URL> codeBaseCacheRef;

    private JceSecurity() {
    }

    static Instance getInstance(String var0, Class<?> var1, String var2, String var3) throws NoSuchAlgorithmException, NoSuchProviderException {
        Service var4 = GetInstance.getService(var0, var2, var3);
        Exception var5 = getVerificationResult(var4.getProvider());
        if (var5 != null) {
            String var6 = "JCE cannot authenticate the provider " + var3;
            throw (NoSuchProviderException)(new NoSuchProviderException(var6)).initCause(var5);
        } else {
            return GetInstance.getInstance(var4, var1);
        }
    }

    static Instance getInstance(String var0, Class<?> var1, String var2, Provider var3) throws NoSuchAlgorithmException {
        Service var4 = GetInstance.getService(var0, var2, var3);
        Exception var5 = getVerificationResult(var3);
        if (var5 != null) {
            String var6 = "JCE cannot authenticate the provider " + var3.getName();
            throw new SecurityException(var6, var5);
        } else {
            return GetInstance.getInstance(var4, var1);
        }
    }

    static Instance getInstance(String var0, Class<?> var1, String var2) throws NoSuchAlgorithmException {
        List var3 = GetInstance.getServices(var0, var2);
        NoSuchAlgorithmException var4 = null;
        Iterator var5 = var3.iterator();

        while(true) {
            Service var6;
            do {
                if (!var5.hasNext()) {
                    throw new NoSuchAlgorithmException("Algorithm " + var2 + " not available", var4);
                }

                var6 = (Service)var5.next();
            } while(!canUseProvider(var6.getProvider()));

            try {
                Instance var7 = GetInstance.getInstance(var6, var1);
                return var7;
            } catch (NoSuchAlgorithmException var8) {
                var4 = var8;
            }
        }
    }

    static javax.vpncrypto.CryptoPermissions verifyExemptJar(URL var0) throws Exception {
        javax.vpncrypto.JarVerifier var1 = new javax.vpncrypto.JarVerifier(var0, true);
        var1.verify();
        return var1.getPermissions();
    }

    static void verifyProviderJar(URL var0) throws Exception {
        javax.vpncrypto.JarVerifier var1 = new javax.vpncrypto.JarVerifier(var0, false);
        var1.verify();
    }

    static synchronized Exception getVerificationResult(Provider var0) {
        Object var1 = verificationResults.get(var0);
        if (var1 == PROVIDER_VERIFIED) {
            return null;
        } else if (var1 != null) {
            return (Exception)var1;
        } else if (verifyingProviders.get(var0) != null) {
            return new NoSuchProviderException("Recursion during verification");
        } else {
            Exception var3;
            try {
                verifyingProviders.put(var0, Boolean.FALSE);
                URL var2 = getCodeBase(var0.getClass());
                verifyProviderJar(var2);
                verificationResults.put(var0, PROVIDER_VERIFIED);
                var3 = null;
                return var3;
            } catch (Exception var7) {
                verificationResults.put(var0, var7);
                var3 = var7;
            } finally {
                verifyingProviders.remove(var0);
            }

            return var3;
        }
    }

    static boolean canUseProvider(Provider var0) {
        return getVerificationResult(var0) == null;
    }

    static URL getCodeBase(final Class<?> var0) {
        synchronized(codeBaseCacheRef) {
            URL var2 = (URL)codeBaseCacheRef.get(var0);
            if (var2 == null) {
                var2 = (URL)AccessController.doPrivileged(new PrivilegedAction<URL>() {
                    public URL run() {
                        ProtectionDomain var1 = var0.getProtectionDomain();
                        if (var1 != null) {
                            CodeSource var2 = var1.getCodeSource();
                            if (var2 != null) {
                                return var2.getLocation();
                            }
                        }

                        return JceSecurity.NULL_URL;
                    }
                });
                codeBaseCacheRef.put(var0, var2);
            }

            return var2 == NULL_URL ? null : var2;
        }
    }

    private static void setupJurisdictionPolicies() throws Exception {
        String var0 = System.getProperty("java.home");
        String var1 = Security.getProperty("crypto.policy");
        Path var2 = var1 == null ? null : Paths.get(var1);
        if (var2 == null || var2.getNameCount() == 1 && var2.compareTo(var2.getFileName()) == 0) {
            if (var2 == null) {
                var2 = Paths.get(var0, "lib", "security");
            } else {
                var2 = Paths.get(var0, "lib", "security", "policy", var1);
            }

            if (debug != null) {
                debug.println("crypto policy directory: " + var2);
            }

            File var3 = new File(var2.toFile(), "US_export_policy.jar");
            File var4 = new File(var2.toFile(), "local_policy.jar");
            if (var1 == null && (!var3.exists() || !var4.exists())) {
                var2 = Paths.get(var0, "lib", "security", "policy", "unlimited");
                var3 = new File(var2.toFile(), "US_export_policy.jar");
                var4 = new File(var2.toFile(), "local_policy.jar");
            }

            URL var5 = ClassLoader.getSystemResource("javax/crypto/Cipher.class");
            if (var5 != null && var3.exists() && var4.exists()) {
                javax.vpncrypto.CryptoPermissions var6 = new javax.vpncrypto.CryptoPermissions();
                javax.vpncrypto.CryptoPermissions var7 = new javax.vpncrypto.CryptoPermissions();
                loadPolicies(var3, var6, var7);
                javax.vpncrypto.CryptoPermissions var8 = new javax.vpncrypto.CryptoPermissions();
                javax.vpncrypto.CryptoPermissions var9 = new javax.vpncrypto.CryptoPermissions();
                loadPolicies(var4, var8, var9);
                if (!var6.isEmpty() && !var8.isEmpty()) {
                    defaultPolicy = var6.getMinimum(var8);
                    if (var7.isEmpty()) {
                        exemptPolicy = var9.isEmpty() ? null : var9;
                    } else {
                        exemptPolicy = var7.getMinimum(var9);
                    }

                } else {
                    throw new SecurityException("Missing mandatory jurisdiction policy files");
                }
            } else {
                throw new SecurityException("Cannot locate policy or framework files!");
            }
        } else {
            throw new SecurityException("Invalid policy directory name format: " + var1);
        }
    }

    private static void loadPolicies(File var0, javax.vpncrypto.CryptoPermissions var1, javax.vpncrypto.CryptoPermissions var2) throws Exception {
        JarFile var3 = new JarFile(var0);
        Enumeration var4 = var3.entries();

        while(var4.hasMoreElements()) {
            JarEntry var5 = (JarEntry)var4.nextElement();
            InputStream var6 = null;

            try {
                if (var5.getName().startsWith("default_")) {
                    var6 = var3.getInputStream(var5);
                    var1.load(var6);
                } else {
                    if (!var5.getName().startsWith("exempt_")) {
                        continue;
                    }

                    var6 = var3.getInputStream(var5);
                    var2.load(var6);
                }
            } finally {
                if (var6 != null) {
                    var6.close();
                }

            }

            javax.vpncrypto.JarVerifier.verifyPolicySigned(var5.getCertificates());
        }

        var3.close();
        var3 = null;
    }

    static javax.vpncrypto.CryptoPermissions getDefaultPolicy() {
        return defaultPolicy;
    }

    static javax.vpncrypto.CryptoPermissions getExemptPolicy() {
        return exemptPolicy;
    }

    static boolean isRestricted() {
        return isRestricted;
    }

    static {
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                public Object run() throws Exception {
                    JceSecurity.setupJurisdictionPolicies();
                    return null;
                }
            });
            isRestricted = !defaultPolicy.implies(javax.vpncrypto.CryptoAllPermission.INSTANCE);
        } catch (Exception var2) {
            throw new SecurityException("Can not initialize cryptographic mechanism", var2);
        }

        PROVIDER_VERIFIED = Boolean.TRUE;

        try {
            NULL_URL = new URL("http://null.oracle.com/");
        } catch (Exception var1) {
            throw new RuntimeException(var1);
        }

        codeBaseCacheRef = new WeakHashMap();
    }
}
